home *** CD-ROM | disk | FTP | other *** search
- #import "Alexandra.h"
- #import "Article.h"
- #import "descriptors.h"
- #import "headerfields.h"
- #import "parsedate.h"
- #import "rfc822realname.h"
- #import "parse-header.h"
- #import "plain-subject.h"
-
- #import <time.h>
- #import <misckit/MiscAppDefaults.h>
- #import "Preferences.subproj/preferences.h"
-
- static BOOL showAuthor,showSubject,showSize;
- static int smallIs,largeIs;
- static int sortType=0;
-
- @implementation Article
-
- + initialize // Ein Article wird erst erzeugt nachdem das main-nib
- { // geladen wurde, d.h. die Default-Defaults sind schon
- // vom Preferences Manager gesetzt!
- if(self==[Article class])
- {
- [self prefsChanged];
- [ERROR_MANAGER addObserver:self
- selector:@selector(prefsChanged) forError:ENOTEPrefsChanged];
- }
- return self;
- }
-
-
- + prefsChanged;
- {
- showAuthor=[NXApp defaultBoolValue:DEFAULT_SHOW_AUTHOR];
- showSubject=[NXApp defaultBoolValue:DEFAULT_SHOW_SUBJECT];
- showSize=[NXApp defaultBoolValue:DEFAULT_SHOW_SIZE];
- smallIs=[NXApp defaultIntValue:DEFAULT_SMALL_ARTICLE];
- largeIs=[NXApp defaultIntValue:DEFAULT_LARGE_ARTICLE];
- return self;
- }
-
- + setSortType:(int)t
- {
- sortType=t;
-
- return self;
- }
-
- + (int)sortType
- {
- return sortType;
- }
-
- - initWithNumber:(long)number
- {
- [self initTextCell:NULL];
- [self setWrap:NO];
- size=0;
- unread=TRUE;
- myNumber=number;
- myHeader.fieldBody=(char **)calloc(FIELD_COUNT,sizeof(char *));
- timeOfPosting=0;
- authorRealName=NULL;
- killed=FALSE;
- return self;
- }
-
- - composeTitle
- {
- char *buf,*p=NULL;
- BOOL a=FALSE;
- BOOL b=FALSE;
- int from,to,tsize=1;
-
- if(showSubject && (p=myHeader.fieldBody[SUBJECT])){
- a=TRUE;
- tsize+=strlen(p);
- }
-
- if(showAuthor && (myHeader.fieldBody[FROM]!=NULL)){
- rfc822_realname(myHeader.fieldBody[FROM],&from,&to);
- if(from<to)
- b=TRUE;
- tsize+=to-from+6;
- }
-
- buf=calloc(tsize,sizeof(char));
- if(a) strcpy(buf,p);
- if(b){
- strcat(buf," (");
- strncat(buf,myHeader.fieldBody[FROM]+from,to-from+1);
- strcat(buf,")");
- }
-
-
- [self setStringValueNoCopy:buf shouldFree:YES];
-
- return self;
- }
-
- - parseHeader:(NXStream *)headerStream;
- {
- char *stream_buffer;
- int len,a;
-
- NXGetMemoryBuffer(headerStream,&stream_buffer,&len,&a);
- parse_header(stream_buffer, len, myHeader.fieldBody, h_field_name, FIELD_COUNT,YES);
-
- return self;
- }
-
- -free
- {
- int i;
-
- for(i=0;i<FIELD_COUNT;i++)
- if(myHeader.fieldBody[i]!=NULL)
- free(myHeader.fieldBody[i]);
- free(myHeader.fieldBody);
- if(authorRealName!=NULL)
- free(authorRealName);
- return([super free]);
- }
-
- - (long)number
- {
- return myNumber;
- }
-
- - (headerDesc *)header
- {
- return &myHeader;
- }
-
- - (time_t)time
- {
- if((timeOfPosting==0)&&(myHeader.fieldBody[DATE]!=NULL)){
- timeOfPosting=parsedate(myHeader.fieldBody[DATE]);
- if(timeOfPosting==-1){
- timeOfPosting=0;
- free(myHeader.fieldBody[DATE]);
- myHeader.fieldBody[DATE]=NULL;
- }
- }
-
- return timeOfPosting;
- }
-
- - (const char *)realName;
- {
- if((authorRealName==NULL)&&(myHeader.fieldBody[FROM]!=NULL)){
- int from,to;
- rfc822_realname(myHeader.fieldBody[FROM],&from,&to);
- if(from<to){
- authorRealName=(char *)malloc((to-from+2)*sizeof(char));
- strncpy(authorRealName,myHeader.fieldBody[FROM]+from,to-from+1);
- authorRealName[to-from+1]='\0';
- }
- }
-
- return authorRealName;
- }
-
- - setRead
- {
- unread=FALSE;
- return self;
- }
-
- - setUnread
- {
- unread=TRUE;
- return self;
- }
-
- - (BOOL)isRead
- {
- return((unread==FALSE)||(killed==TRUE));
- }
-
- - kill
- {
- killed=TRUE;
- return self;
- }
-
- - unkill
- {
- killed=FALSE;
- return self;
- }
-
- - (BOOL)isKilled
- {
- return killed;
- }
-
- - setTextAttributes:textObj
- {
- [super setTextAttributes:textObj];
- if (unread==FALSE)
- [textObj setTextGray:NX_DKGRAY];
- else
- [textObj setTextGray:NX_BLACK];
- return textObj;
- }
-
- - unsetTag
- {
- myTag=0;
- return self;
- }
-
- - setTag
- {
- myTag=1;
- return self;
- }
-
- - (BOOL)isTaged
- {
- return((myTag==1)&&(killed==FALSE));
- }
-
- - (int)size
- {
- return size;
- }
-
- - setSize:(int)asize;
- {
- size=asize;
- return self;
- }
-
-
-
- - (int)lines;
- {
- return lines;
- }
-
-
- - setLines:(int)lineCount;
- {
- lines=lineCount;
- return self;
- }
-
- //------------------------------------
- // MiscCompare protocol implementation
- //------------------------------------
- - (int)compare:anObject
- {
- int result=0;
- BOOL r1,r2;
- const char *s1,*s2;
- headerDesc *h1,*h2;
-
- switch (sortType) {
- case SORT_BY_DATE:
- result=[self time]-[anObject time];
- break;
- case SORT_BY_SUBJECT:
- h1=[self header];
- h2=[anObject header];
- if(!h1 || !h2){
- NXLogError("Article.m: article header is NULL pointer");
- return 0;
- }
- s1=plain_subject(h1->fieldBody[SUBJECT],&r1);
- s2=plain_subject(h2->fieldBody[SUBJECT],&r2);
-
- if((s1==NULL)&&(s2==NULL)) result=0;
- else if(s1==NULL) result=-1;
- else if(s2==NULL) result=1;
- else
- result=strcasecmp(s1,s2);
- if(result==0)
- if(r1!=r2)
- result=(r1? 1:-1);
- else
- result=[self time]-[anObject time];
- break;
- case SORT_BY_NUMBER:
- result=[self number]-[anObject number];
- break;
- case SORT_BY_REAL_NAME:
- s1=[self realName];
- s2=[anObject realName];
- if((s1==NULL)&&(s2==NULL)) result=0;
- else if(s1==NULL) result=-1;
- else if(s2==NULL) result=1;
- else
- result=strcasecmp(s1,s2);
- break;
- }
-
- return result;
- }
-
- //-----------------------------------------------------------
- // fancy drawing...
- //-----------------------------------------------------------
-
- #define IMAGEMARGIN 1.0
-
- - calcCellSize:(NXSize *)theSize inRect:(const NXRect *)aRect
- {
- [super calcCellSize:theSize inRect:aRect];
- theSize->height+=1;
- return self;
- }
-
-
- - drawInside:(const NXRect *)cellFrame inView:controlView
- {
- static NXImage *dotImages[] = { nil, nil, nil };
- NXRect rect = *cellFrame;
- NXPoint imageOrigin;
- NXSize dotSize;
- int sizecat;
- struct _cFlags1 buf;
-
- if(!dotImages[0])
- {
- dotImages[0] = [NXImage findImageNamed:"Article-short"];
- dotImages[1] = [NXImage findImageNamed:"Article-medium"];
- dotImages[2] = [NXImage findImageNamed:"Article-long"];
- }
- [dotImages[2] getSize:&dotSize];
-
- PSsetgray((cFlags1.state || cFlags1.highlighted) ? NX_WHITE : NX_LTGRAY);
- NXRectFill(cellFrame);
-
- if(showSize && (lines>0))
- {
- imageOrigin.x = NX_MAXX(cellFrame) - IMAGEMARGIN * 2.0 - dotSize.width;
- imageOrigin.y = NX_Y(cellFrame) + NX_HEIGHT(cellFrame) -
- (NX_HEIGHT(cellFrame) - dotSize.height) / 2.0;
- if(lines<=smallIs)
- sizecat=0;
- else if(lines<=largeIs)
- sizecat=1;
- else
- sizecat=2;
- [dotImages[sizecat] composite:NX_SOVER toPoint:&imageOrigin];
- NX_WIDTH(&rect) -= (dotSize.width + IMAGEMARGIN * 2.0 - NX_X(&rect));
- }
- buf=cFlags1;
- cFlags1.highlighted=cFlags1.state=0;
- [super drawInside:&rect inView:controlView];
- cFlags1=buf;
-
- PSsetgray(NX_DKGRAY);
- if (cFlags1.state || cFlags1.highlighted)
- {
- NXRect rectArray[2];
-
- NXSetRect(&(rectArray[0]),NX_X(cellFrame),NX_Y(cellFrame),
- NX_WIDTH(cellFrame),1);
- NXSetRect(&(rectArray[1]),NX_X(cellFrame),NX_MAXY(cellFrame)-1,
- NX_WIDTH(cellFrame), 1.0);
- NXRectFillList(rectArray, 2);
- }
- return self;
- }
-
-
- - highlight:(const NXRect *)cellFrame inView:controlView lit:(BOOL)flag
- {
- if(cFlags1.highlighted != flag)
- {
- cFlags1.highlighted = flag;
- [self drawInside:cellFrame inView:controlView];
- }
- return self;
- }
-
-
-
- @end
-